/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright 2006 - 2009 Pentaho Corporation. All rights reserved.
*
*
* @created Dec 22, 2006
* @author James Dixon
*
*/
package org.pentaho.platform.plugin.outputs;
import java.io.InputStream;
import java.util.Calendar;
import java.util.StringTokenizer;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;
import javax.jcr.lock.LockException;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
import javax.jcr.version.VersionIterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.exception.NestableRuntimeException;
import org.pentaho.platform.api.engine.IContentListener;
import org.pentaho.platform.api.repository.IContentItem;
import org.pentaho.platform.engine.core.output.BufferedContentItem;
import org.pentaho.platform.plugin.services.messages.Messages;
import org.pentaho.platform.engine.services.outputhandler.BaseOutputHandler;
import org.pentaho.platform.util.logging.Logger;
import org.pentaho.platform.util.messages.LocaleHelper;
public abstract class JcrCmsOutputHandler extends BaseOutputHandler {
public abstract Repository getRepository();
private static final Log logger = LogFactory.getLog(JcrCmsOutputHandler.class);
public abstract Session getJcrSession(Repository repository);
@Override
public IContentItem getFileOutputContentItem() {
String contentName = getContentRef();
try {
Repository repository = getRepository();
if (repository == null) {
Logger.error(JcrCmsOutputHandler.class.getName(), Messages.getInstance()
.getString("JcrCmsOutputHandler.ERROR_0001_GETTING_CMSREPO")); //$NON-NLS-1$
return null;
}
Session jcrSession = getJcrSession(repository);
if (jcrSession == null) {
Logger.error(JcrCmsOutputHandler.class.getName(), Messages.getInstance()
.getString("JcrCmsOutputHandler.ERROR_0002_GETTING_SESSION")); //$NON-NLS-1$
return null;
}
// Use the root node as a starting point
Node root = jcrSession.getRootNode();
if (root == null) {
Logger.error(JcrCmsOutputHandler.class.getName(), Messages.getInstance()
.getString("JcrCmsOutputHandler.ERROR_0003_GETTING_ROOT")); //$NON-NLS-1$
return null;
}
Node node = root;
// parse the path
StringTokenizer tokenizer = new StringTokenizer(contentName, "/"); //$NON-NLS-1$
int levels = tokenizer.countTokens();
for (int idx = 0; idx < levels - 1; idx++) {
String folder = tokenizer.nextToken();
if (!node.hasNode(folder)) {
// Create an unstructured node under which to import the XML
node = node.addNode(folder, "nt:folder"); //$NON-NLS-1$
} else {
node = node.getNodes(folder).nextNode();
}
}
// we should be at the right level now
String fileName = tokenizer.nextToken();
Node fileNode = null;
Node contentNode = null;
Version version = null;
if (node.hasNode(fileName)) {
fileNode = node.getNode(fileName);
contentNode = fileNode.getNode("jcr:content"); //$NON-NLS-1$
if (contentNode.isLocked()) {
JcrCmsOutputHandler.logger
.warn(Messages.getInstance().getString("JcrCmsOutputHandler.ERROR_0004_NODE_LOCKED", contentName)); //$NON-NLS-1$
return null;
}
if (contentNode.isCheckedOut()) {
JcrCmsOutputHandler.logger.warn(Messages.getInstance().getString(
"JcrCmsOutputHandler.ERROR_0005_NODE_CHECKED_OUT", contentName)); //$NON-NLS-1$
return null;
}
contentNode.checkout();
VersionHistory history = contentNode.getVersionHistory();
VersionIterator iterator = history.getAllVersions();
while (iterator.hasNext()) {
version = iterator.nextVersion();
JcrCmsOutputHandler.logger.trace(version.getPath()
+ "," + version.getName() + "," + version.getIndex() + "," + version.getCreated().toString()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
} else {
fileNode = node.addNode(fileName, "nt:file"); //$NON-NLS-1$
fileNode.addMixin("mix:versionable"); //$NON-NLS-1$
// create the mandatory child node - jcr:content
contentNode = fileNode.addNode("jcr:content", "nt:resource"); //$NON-NLS-1$ //$NON-NLS-2$
contentNode.addMixin("mix:versionable"); //$NON-NLS-1$
contentNode.addMixin("mix:filename"); //$NON-NLS-1$
contentNode.setProperty("jcr:mimeType", getMimeType()); //$NON-NLS-1$
contentNode.setProperty("jcr:name", fileName); //$NON-NLS-1$
contentNode.setProperty("jcr:encoding", LocaleHelper.getSystemEncoding()); //$NON-NLS-1$
}
CmsContentListener listener = new CmsContentListener(contentNode, jcrSession);
BufferedContentItem contentItem = new BufferedContentItem(listener);
listener.setContentItem(contentItem);
if (false) { // Disable faked search for now
search("test", jcrSession); //$NON-NLS-1$
}
return contentItem;
} catch (LockException le) {
Logger.error(JcrCmsOutputHandler.class.getName(), Messages.getInstance()
.getString("JcrCmsOutputHandler.ERROR_0006_GETTING_OUTPUTHANDLER") + contentName, le); //$NON-NLS-1$
} catch (NestableRuntimeException nre) {
Logger.error(JcrCmsOutputHandler.class.getName(), Messages.getInstance()
.getString("JcrCmsOutputHandler.ERROR_0006_GETTING_OUTPUTHANDLER") + contentName, nre); //$NON-NLS-1$
} catch (RepositoryException re) {
Logger.error(JcrCmsOutputHandler.class.getName(), Messages.getInstance()
.getString("JcrCmsOutputHandler.ERROR_0006_GETTING_OUTPUTHANDLER") + contentName, re); //$NON-NLS-1$
}
return null;
}
private void search(final String searchStr, final Session session) {
try {
Workspace workspace = session.getWorkspace();
QueryManager queryManager = workspace.getQueryManager();
Query query = queryManager.createQuery("//*[jcr:contains(., '" + searchStr + "')]", Query.XPATH); //$NON-NLS-1$ //$NON-NLS-2$
QueryResult result = query.execute();
NodeIterator it = result.getNodes();
while (it.hasNext()) {
Node n = it.nextNode();
JcrCmsOutputHandler.logger.trace(n.getName());
if (n.getName().equals("jcr:content")) { //$NON-NLS-1$
if (n.getProperty("jcr:mimeType") != null) { //$NON-NLS-1$
JcrCmsOutputHandler.logger.trace("jcr:mimeType=" + n.getProperty("jcr:mimeType").getString()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
} catch (InvalidQueryException iqe) {
Logger.error(JcrCmsOutputHandler.class.getName(), Messages.getInstance()
.getString("JcrCmsOutputHandler.ERROR_0008_SEARCH_FAILED"), iqe); //$NON-NLS-1$
} catch (RepositoryException re) {
Logger.error(JcrCmsOutputHandler.class.getName(), Messages.getInstance()
.getString("JcrCmsOutputHandler.ERROR_0008_SEARCH_FAILED"), re); //$NON-NLS-1$
}
}
private class CmsContentListener implements IContentListener {
private Node node;
private Session session;
private BufferedContentItem contentItem;
public CmsContentListener() {
}
public CmsContentListener(final Node node, final Session session) {
this.node = node;
this.session = session;
}
public void close() {
try {
InputStream inputStream = contentItem.getInputStream();
node.setProperty("jcr:data", inputStream); //$NON-NLS-1$
Calendar lastModified = Calendar.getInstance();
node.setProperty("jcr:lastModified", lastModified); //$NON-NLS-1$
session.save();
node.checkin();
session.save();
} catch (LockException le) {
Logger.error(JcrCmsOutputHandler.class.getName(), Messages.getInstance()
.getString("JcrCmsOutputHandler.ERROR_0007_SAVING_CONTENT"), le); //$NON-NLS-1$
} catch (RepositoryException re) {
Logger.error(JcrCmsOutputHandler.class.getName(), Messages.getInstance()
.getString("JcrCmsOutputHandler.ERROR_0007_SAVING_CONTENT"), re); //$NON-NLS-1$
}
}
public void setNode(final Node node) {
this.node = node;
}
public void setSession(final Session session) {
this.session = session;
}
public void setContentItem(final BufferedContentItem contentItem) {
this.contentItem = contentItem;
}
public void setMimeType(final String mimeType) {
}
public void setName(final String Name) {
}
}
}